﻿namespace Pibby.Core.IO
{
	public class DiskSpaceInfo
	{
		#region Variables

		private long currentValue;
		private long maximumValue;
		private long warningThreshold;
		private long dangerThreshold;

		#endregion Variables

		#region Constructors

		public DiskSpaceInfo()
		{
			this.Value = 0;
			this.Maximum = 100;
			this.DangerThreshold = 90;
			this.WarningThreshold = 80;
		}

		public DiskSpaceInfo(IDrive drive)
			: this(drive.AvailableFreeSpace, drive.TotalSize)
		{
		}

		public DiskSpaceInfo(long availableFreeSpace, long totalSize)
		{
			this.Maximum = totalSize;
			this.FreeSpace = availableFreeSpace;
		}

		#endregion Constructors

		#region Properties

		public DiskSpaceStatus Status
		{
			get
			{
				DiskSpaceStatus currentStatus = DiskSpaceStatus.Normal;

				if (this.Value == this.Maximum)
				{
					currentStatus = DiskSpaceStatus.Full;
				}
				else if (this.Value >= this.DangerThreshold)
				{
					currentStatus = DiskSpaceStatus.Danger;
				}
				else if (this.Value > this.WarningThreshold)
				{
					currentStatus = DiskSpaceStatus.Warning;
				}
				
				return currentStatus;
			}
		}

		public long Value
		{
			get 
			{ 
				return this.currentValue; 
			}

			set
			{
				this.currentValue = value;

				if (this.currentValue > this.maximumValue)
				{
					this.currentValue = this.maximumValue;
				}

				if (this.currentValue < 0)
				{
					this.currentValue = 0;
				}
			}
		}

		public long FreeSpace
		{
			get 
			{ 
				return this.Maximum - this.Value; 
			}

			set
			{
				this.Value = this.Maximum - value;
			}
		}

		public long Range
		{
			get { return this.Maximum; }
		}

		public int ValueAsPercent
		{
			get
			{
				return (int)(((double)this.Value * 100.0) / (double)this.Range);
			}
		}

		public int SafeRegionAsPercent
		{
			get
			{
				return (int)(((double)this.WarningThreshold * 100.0) / (double)this.Range);
			}
		}

		public int WarningRegionAsPercent
		{
			get
			{
				return (int)(((double)(this.DangerThreshold - this.WarningThreshold) * 100.0) / (double)this.Range);
			}
		}

		public int DangerRegionAsPercent
		{
			get
			{
				return (int)(((double)(this.Maximum - this.DangerThreshold) * 100.0) / (double)this.Range);
			}
		}
		
		public long Maximum
		{
			get 
			{
				return this.maximumValue; 
			}

			set
			{
				this.maximumValue = value;

				if (this.currentValue > value)
				{
					this.currentValue = value;
				}

				if (this.warningThreshold > value)
				{
					this.warningThreshold = value;
				}
				else
				{
					this.warningThreshold = (long)(0.75 * (double)value);
				}

				if (this.dangerThreshold > value)
				{
					this.dangerThreshold = value;
				}
				else
				{
					this.dangerThreshold = (long)(0.9 * (double)value);
				}
			}
		}

		public long WarningThreshold
		{
			get 
			{
				return this.warningThreshold; 
			}

			set
			{
				this.warningThreshold = value;

				if (value > this.maximumValue)
				{
					this.warningThreshold = this.maximumValue;
				}
			}
		}

		public long DangerThreshold
		{
			get 
			{ 
				return this.dangerThreshold; 
			}

			set
			{
				this.dangerThreshold = value;

				if (value > this.maximumValue)
				{
					this.dangerThreshold = this.maximumValue;
				}
			}
		}

		#endregion Properties
	}
}
